package com.fanrui.code.chess.mahjong;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.fanrui.code.chess.AbstractChessCard;
import com.fanrui.code.chess.IChessCard;
import com.fanrui.code.mahjong.util.MahjongCardUtil;
import com.fanrui.proto.cmd.MahjongType;
import com.fanrui.proto.cmd.WannengType;
import com.google.gson.annotations.Expose;

public class Mahjong extends AbstractChessCard {

	/**
	 * 类型
	 */
	@Expose
	private MahjongType type;

	/**
	 * 万能牌类型
	 */
	@Expose
	private WannengType wannengType;

	public Mahjong(int id, int number, MahjongType type, WannengType wannengType) {
		super(id, number);
		this.type = type;
		this.wannengType = wannengType;
	}

	public MahjongType getType() {
		return type;
	}

	public void setType(MahjongType type) {
		this.type = type;
	}

	public WannengType getWannengType() {
		return wannengType;
	}

	public void setWannengType(WannengType wannengType) {
		this.wannengType = wannengType;
	}

	@Override
	public Mahjong cloneCard() {
		return new Mahjong(this.getId(), this.getNumber(), type, wannengType);
	}

	@Override
	public int compareTo(IChessCard o) {
		if(!(o instanceof Mahjong)){
			return -1;
		}
		Mahjong other = ((Mahjong) o);
		
		if(other.getType().getNumber() < getType().getNumber()){
			return 1;
		}
		if(other.getType().getNumber() > getType().getNumber()){
			return -1;
		}
		if(other.getNumber() < getNumber()){
			return 1;
		}
		if(other.getNumber() > getNumber()){
			return -1;
		}
		if(other.getId() < getId()){
			return 1;
		}
		if(other.getId() > getId()){
			return -1;
		}
		return 0;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (obj == this) {
			return true;
		}
		if (!(obj instanceof Mahjong)) {
			return false;
		}

		Mahjong card = (Mahjong) obj;
		return card.getNumber() == getNumber() && card.getType() == getType() && card.getId() == getId();
	}
	
	/**  
	*  只检测花色和点数
	*  @param obj
	*  @return    
	*  boolean    
	*/  
	public boolean cardEquals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (obj == this) {
			return true;
		}
		if (!(obj instanceof Mahjong)) {
			return false;
		}

		Mahjong card = (Mahjong) obj;
		return card.getNumber() == getNumber() && card.getType() == getType();
	}
	
	/**  
	*  只检测花色和点数
	*  @param obj
	*  @return    
	*  boolean    
	*/  
	public boolean cardEquals(com.fanrui.proto.cmd.Mahjong mahjong) {
		if (mahjong == null) {
			return false;
		}
		return mahjong.getNumber() == getNumber() && mahjong.getType() == getType();
	}

	/**
	 * 这种17和31散列码的想法来自经典的Java书籍——《Effective Java》第九条。
	 */
	@Override
	public int hashCode() {
		int result = 17;
		result = 31 * result + getType().hashCode();
		result = 31 * result + getNumber();
		return result;
	}
	
	@Override
	public String toString() {
		return "[" + getId() + "-" + type.name() + "-" + getNumber() + "]";
	}

	public Mahjong getNext(){
		if(getNumber() == 9){
			return null;
		}
		return MahjongCardUtil.getMahjong(getNumber()+1, type);
	}
	
	public Mahjong getUpper() {
		if(getNumber() == 1) {
			return null;
		}
		return MahjongCardUtil.getMahjong(getNumber()-1, type);
	}

	public com.fanrui.proto.cmd.Mahjong toCardCmd() {
		com.fanrui.proto.cmd.Mahjong.Builder builder = com.fanrui.proto.cmd.Mahjong.newBuilder();
		builder.setCid(getId());
		builder.setType(type);
		builder.setNumber(getNumber());
		if(wannengType != null) {
			builder.setWannengType(wannengType);
		}
		return builder.build();
	}

	public static List<Mahjong> clone(Collection<Mahjong> cards) {
		List<Mahjong> result = new ArrayList<Mahjong>();
		if (cards != null) {
			for (Mahjong card : cards) {
				if(card != null){
					result.add(card.cloneCard());
				}
			}
		}
		return result;
	}

	public Mahjong getNextN(int i){
		if(getNumber() + i > 9 || getNumber() + i < 1){
			return null;
		}
		return MahjongCardUtil.getMahjong(getNumber()+i, type);
	}

	/**
	 * 返回下一张牌9返回1，东南西北（北返回东）
	 * 中发白（白返回中）
	 * @return
	 */
	public Mahjong getNextMahjong() {
		if(this.getType() == MahjongType.SAN) {
			if(this.getNumber() == 4) {
				return MahjongCardUtil.getMahjong(1, type);
			}
			if(this.getNumber() == 7) {
				return MahjongCardUtil.getMahjong(5, type);
			}
		}else if(this.getNumber() == 9){
			return MahjongCardUtil.getMahjong(1, type);
		}
		return MahjongCardUtil.getMahjong(getNumber()+1, type);
	}
}
